﻿using System.Linq;
using Hvam.SharePoint.Search.Language.Parsers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Hvam.SharePoint.Search.Tests.Internal.Language.Parsers
{
    [TestClass]
    public class CharParserTests
    {
        [TestMethod]
        public void CharParserWhitespaceTrue()
        {
            // Arrange
            const string input = " ";

            // Act
            var result = CharParser.WhiteSpace.Parse(input);

            // Assert
            Assert.AreEqual(' ', result);
        }

        [TestMethod]
        [ExpectedException(typeof(ParseException))]
        public void CharParserWhitespaceFalse()
        {
            // Arrange
            const string input = "a";

            // Act
            CharParser.WhiteSpace.Parse(input);
        }

        [TestMethod]
        [ExpectedException(typeof(ParseException))]
        public void CharParserWhitespaceEmpty()
        {
            // Arrange
            var s = string.Empty;

            // Act
            CharParser.WhiteSpace.Parse(s);
        }

        [TestMethod]
        public void CharParserEnd()
        {
            // Arrange
            var s = string.Empty;

            // Act
            var result = CharParser.End<string>().Parse(s);

            // Assert
            Assert.AreEqual(default(string), result);
        }

        [TestMethod]
        public void CharParserSelect()
        {
            // Arrange
            const string input = "hvam";

            var parser =
                from h in CharParser.Char('h')
                from v in CharParser.Char('v')
                from a in CharParser.Char('a')
                from m in CharParser.Char('m')
                from eol in CharParser.End<char>()
                select new string(new[] {h, v, a, m});

            // Act
            var result = parser.Parse(input);

            // Assert
            Assert.AreEqual(input, result);
        }

        [TestMethod]
        public void CharParserAtLeastOnce()
        {
            // Arrange
            const string input = "aaaaab";

            var parser =
                from a in CharParser.Char('a').AtLeastOnce()
                select new string(a.ToArray());

            // Act
            var result = parser.Parse(input);
            
            // Assert
            Assert.AreEqual("aaaaa", result);
        }

        [TestMethod]
        public void CharParserLetter()
        {
            // Arrange
            const string input = "aaaaa1";

            var parser =
                from a in CharParser.Letter.AtLeastOnce()
                select new string(a.ToArray());

            // Act
            var result = parser.Parse(input);

            // Assert
            Assert.AreEqual("aaaaa", result);
        }
    }
}
